<?
    ////////////////////////////////////////////////////
    // WISP
    // Web development with Integrated Scripts and PHP
    //
    // Copyright 2008 (c) Joe Chrzanowski
    ////////////////////////////////////////////////////
    
    // Configurations
    
    // Be extremely careful with WISPConf objects.
    // Any paths that must be determined go through the WISPConf object
    // Therefore, you can modify the entire framework structure by 
    // modifying the path variables within the WISPConf object.
    
    // If you mess this up you might have a tough time fixing it.
    class WISPConf {
        const FS = 'fspath';
        const WEB = 'webpath';
        const OTHER = 'nullpath';
        
        private static $_title = 'Default';
        private static $_debug = false;
        private static $_init = false;
        private static $_loadedobjects = array();
        
        // Naming for the paths:
        // [varname]        another variable from the $_paths array
        // {varname}        a dynamic variable, passed to ParsePath
        // <varname>        a $_SERVER variable
        private static $_paths = array(
            'relpath' => '/wisp',
            
            'webpath' => '[relpath]',
            'fspath' => '<DOCUMENT_ROOT>[relpath]',
            'nullpath' => '',
            
            // specify paths to different types of data
            'base' => '/include',                                       // Folder that holds the core WISP functionality
            'packages' => 'packages',                                   // base folder that holds all packages
            'package' => '[packages]/{package}.pkg',                    // location of a specific package (ex: Alerts/Message => packages/Alerts/Message.pkg
            'packageimage' => '[package]/img/{image}',              // location of an image resource 
            'packagescript' => '[package]/js/{script}.js',              // a javascript file for some certain package    
            'packagecss' => '[package]/css/{css}.css',                  // a css file for some certain package
            'packagelayout' => '[package]/layouts/{layout}.layout.xml', // layouts for this package
            'packagetest' => '[package]/tests/{testfile}.test.php',     // folder to store tests for the packages
            
            'themes' => 'themes',
            'theme' => '[themes]/{theme}',                              // get the address of a theme
            'themeimage' => '[theme]/img/{image}',                  // get an image from the theme
            'themescript' => '[theme]/js/{script}.js',                  // get a script from the theme
            'themecss' => '[theme]/css/{css}.css',                      // get a stylesheet from the menu
            'themelayout' => '[theme]/layouts/{layout}.layout.xml'      // layout files for the theme   
        );
        private static $_options = array(
            'debug' => false,
            'handle_exceptions' => true,
        );
        
        function __construct() { throw new Exception("ERROR: You can't instantiate a WISPConf object"); }
        
        static function PackageExists($package) {
            $path = self::GetPath(FS,'package',array('package' => $package));
            if (is_dir($path)) return true;
            else return false;
        }
        static function ThemeExists($theme) {
            $path = self::GetPath(WISPConf::FS,'theme',array('theme' => $theme));
            if (is_dir($path)) return true;
            else return false;
        }
        
         // get a full path
        static function GetPath($type, $path, $vars = null) {
            if (self::$_paths[$path]) {
                $parsedpath = self::ResolvePaths("[$type]") . '/' . self::ResolvePaths(self::$_paths[$path]);
                $parsedpath = self::ResolveArgs($parsedpath,$vars);
                
                // make it look right
                while (strpos($parsedpath,'//') !== false)
                    $parsedpath = preg_replace("/\/+/","/",$parsedpath);  
                
                return $parsedpath;
            }
            else return '';
        }
        
        
        static function PushObject($objname) {
            self::$_loadedobjects[] = $objname;
        }
        
        // make sure the paths are only getting parsed once per page load
        static function PreParse() {
            foreach (self::$_paths as $path => $parse) {
                self::$_paths[$path] = self::ResolvePaths($parse);
            }
        }
        
        // resolve paths using other variabels from the $_paths array
        // also replace any <VAR> vars with $_SERVER[VAR]
        static function ResolvePaths($path) {
            $matches = array();
            
            while (preg_match_all('/\[(\w+)]/',$path, $matches)) {
                foreach ($matches[1] as $match) {
                    $path = str_replace("[$match]",self::$_paths[$match],$path);
                }
            }
            preg_match_all('/<(\w+)>/',$path, $matches);
            foreach ($matches[1] as $match) {
                $path = str_replace("<$match>",$_SERVER[$match],$path);
            }
            
            return $path;
        }
        
        // get a path using specific arguments
        // example:
        //      ResolveArgs('image',array('package'=>'Alerts/Message', 'image' => 'error'));
        // returns the path to the error.png image relative to the wisp root folder
        static function ResolveArgs($path,$vars) {
            $matches = array();
            
            if (!is_array($vars)) return $path;
            
            foreach ($vars as $key => $val) {
                $path = str_replace("{" . $key . "}",$val,$path);
            }
            return $path;
        }
        
        // initialize wisp
        static function Init() {
            if (!self::$_init) {
                self::PreParse();
                $objects = scandir(self::GetPath(self::FS,'base'));
                foreach ($objects as $file) {
                    if ($file[0] != ".") {
                        $include = self::GetPath(self::FS, 'base') . "/$file";
                        require_once($include);
                    }
                }
                self::$_init = true;
            }
        }
        static function GetOption($opt) { return self::$_options[$opt]; }
    }
    
    // initialize WISP
    WISPConf::Init();
    
    // Import basic packages
    WISPUtil::Import("Advanced/Exceptions");
    WISPUtil::Import("HTML/Standard");
    WISPUtil::Import("Alerts/Messages");    
?>